import { NextFunction, Request, Response as ExpressResponse } from "express";
import { SessionDataType } from "types/session";

export interface Response extends ExpressResponse {
    sendResponse?: (status: number, data?: unknown, message?: null | string) => void;
    handleError?: (error: any | unknown) => void;
}

export interface Service {
    (req: Request & { session: SessionDataType }, res: Response): Promise<void> | void;
}

export const responseMiddleware = (req: Request, res: Response, next: NextFunction) => {
    // 自定义一个函数来构造统一的响应
    const sendResponse: Response["sendResponse"] = (status, data = null, message = null) => {
        if (res.headersSent) return;
        res.status(200).json({
            status,
            data,
            message: message || (status >= 200 && status < 300 ? "请求成功" : "请求失败"),
        });
    };
    // 统一处理错误
    const handleError: Response["handleError"] = (error: any) => {
        if (typeof error === "string") return sendResponse(400, null, error);
        //一般是mongoose报错
        if (error.errorResponse?.errmsg) return sendResponse(400, null, `参数错误: ${error.errorResponse.errmsg}`);

        //不是Error对象
        if (!(error instanceof Error)) return sendResponse(500, null, "请求失败");

        //参数格式校验失败
        const paramsErrorKeywords = ["not a valid enum", "is required", "must be a 24 character"];
        if (paramsErrorKeywords.some(item => error.message.includes(item))) return sendResponse(400, null, `参数错误: ${error.message}`);

        //其它报错，兜底
        sendResponse(500, null, error.message || "请求失败");
    };

    // 将函数挂载到res上，以便在其他中间件或路由中使用
    res.sendResponse = sendResponse;
    res.handleError = handleError;

    // 调用next()以将控制权传递给下一个中间件或路由
    next();
};
